import TyOverlayexLayer from './TyOverlayexLayer'
import TyOverlayex from './TyOverlayex'
import Draw from 'ol/interaction/Draw'
import VectorSource from 'ol/source/Vector'
import VectorLayer from 'ol/layer/Vector'
import {Circle as CircleStyle, Fill, Stroke, Style} from 'ol/style'
import {LineString, Polygon} from 'ol/geom'
import {unByKey} from 'ol/Observable'
import {getArea, getLength} from 'ol/sphere'
import '@/components/common-map/style/tooltip.scss'
import $ from 'jquery'

// 测距测面积工具
class TyMeasureTool {
  constructor(map) {
    this.map = map
    this.isGeodesic = map.getView().getProjection().getCode().toUpperCase() === 'EPSG:4326'// 是否是地理坐标（经纬度坐标、4326坐标）ol.proj.Units.degrees
    this.draw = null
    // 当前绘制的特征
    this.sketch = null
    this.sketchChangelistener = null
    this.helpTooltip = null
    this.measureTooltip = null
    this.style = new Style({
      fill: new Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      }),
      stroke: new Stroke({
        color: '#ffcc33',
        width: 2
      }),
      image: new CircleStyle({
        radius: 7,
        fill: new Fill({
          color: '#ffcc33'
        })
      })
    })
    this.vecSource = new VectorSource({
      useSpatialIndex: false,
      wrapX: false
    })

    this.vecLayer = new VectorLayer({
      style: this.style,
      map: this.map,
      source: this.vecSource
    })
    this.overlayexs = new TyOverlayexLayer({
      id: 'TyMapUtils.MeasureTool',
      map: this.map
    })
  }

  // 鼠标移动时，tooltip跟随;
  pointerMoveHandler = (evt) => {
    if (evt.dragging) {
      return
    }
    let helpMsg = '单击开始绘图'
    const continuePolygonMsg = '单击以继续绘制多边形'
    const continueLineMsg = '单击以继续绘制线条'
    if (this.sketch) {
      const geom = (this.sketch.getGeometry())
      if (geom instanceof Polygon) {
        helpMsg = continuePolygonMsg
      } else if (geom instanceof LineString) {
        helpMsg = continueLineMsg
      }
    }
    this.helpTooltip.setContent(helpMsg)
    this.helpTooltip.setPosition(evt.coordinate)
    $(this.helpTooltip.getHtmlElement()).removeClass('hidden')
  }

  // 鼠标移出地图时，隐藏tooltip
  mouseMoveHandler = (evt) => {
    $(this.helpTooltip.getHtmlElement()).addClass('hidden')
  }

  onDrawStart = (evt) => {
    // set sketch
    this.sketch = evt.feature
    let tooltipCoord = evt.coordinate
    this.sketchChangelistener = this.sketch.getGeometry().on('change', (evt) => {
      const geom = evt.target
      let output
      if (geom instanceof Polygon) {
        output = this.formatArea(geom)
        tooltipCoord = geom.getInteriorPoint().getCoordinates()
      } else if (geom instanceof LineString) {
        output = this.formatLength(geom)
        tooltipCoord = geom.getLastCoordinate()
      }
      // measureTooltipElement.innerHTML = output;
      this.measureTooltip.setContent(output)
      this.measureTooltip.setPosition(tooltipCoord)
    })
  }

  onDrawEnd = (evt) => {
    this.measureTooltip.getHtmlElement().className = 'tooltip tooltip-static'
    this.measureTooltip.setOffset([0, -7])
    // unset sketch
    this.sketch = null
    this.createMeasureTooltip()
    unByKey(this.sketchChangelistener)
  }

  // 创建新的帮助工具提示
  createHelpTooltip() {
    const dom = '<div class="tooltip hidden"></div>'
    const helpTooltipElement = $(dom).appendTo($('body'))[0]
    this.helpTooltip = new TyOverlayex({
      offset: [15, 0],
      container: helpTooltipElement,
      positioning: 'center-left'
    })
    this.overlayexs.addOverlayex(this.helpTooltip)
  }

  // 创建新的度量值工具提示
  createMeasureTooltip() {
    const dom = '<div class="tooltip tooltip-measure"></div>'
    const measureTooltipElement = $(dom).appendTo($('body'))[0]
    this.measureTooltip = new TyOverlayex({
      offset: [0, -15],
      container: measureTooltipElement,
      positioning: 'bottom-center'
    })
    this.overlayexs.addOverlayex(this.measureTooltip)
  }

  // 返回线的长度
  formatLength(line) {
    let length
    if (this.isGeodesic) {
      length = getLength(line, {projection: this.map.getView().getProjection()})
    } else {
      length = Math.round(line.getLength() * 100) / 100
    }
    let output
    if (length > 1000) {
      output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km'
    } else {
      output = (Math.round(length * 100) / 100) + ' ' + 'm'
    }
    return output
  }

  // 返回面积
  formatArea(polygon) {
    let area
    if (this.isGeodesic) {
      area = getArea(polygon, {projection: this.map.getView().getProjection()})
    } else {
      area = polygon.getArea()
    }
    let output
    if (area > 100000) {
      output = (Math.round(area / 1000000 * 100) / 100) + ' ' + 'km<sup>2</sup>'
    } else {
      output = (Math.round(area * 100) / 100) + ' ' + 'm<sup>2</sup>'
    }
    return output
  }

  // 开始绘制 长度与面积
  start(typeValue) {
    const type = (typeValue === 'area' ? 'Polygon' : 'LineString')
    if (this.draw) {
      this.map.removeInteraction(this.draw)
    }
    this.createMeasureTooltip()
    this.createHelpTooltip()
    this.map.on('pointermove', this.pointerMoveHandler)
    $(this.map.getViewport()).on('mouseout', this.mouseMoveHandler)
    this.draw = new Draw({
      source: this.vecSource,
      type: type,
      // 绘制时的样式；
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: 'rgba(0, 0, 0, 0.5)',
          lineDash: [10, 10],
          width: 2
        }),
        image: new CircleStyle({
          radius: 5,
          stroke: new Stroke({
            color: 'rgba(0, 0, 0, 0.7)'
          }),
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          })
        })
      })
    })
    this.map.addInteraction(this.draw)
    this.draw.on('drawstart', this.onDrawStart)
    this.draw.on('drawend', this.onDrawEnd)
  }

  close(flag = true) {
    this.map.un('pointermove', this.pointerMoveHandler)
    $(this.map.getViewport()).off('mouseout', this.mouseMoveHandler)
    this.overlayexs.removeOverlayex(this.helpTooltip)
    this.overlayexs.removeOverlayex(this.measureTooltip)
    if (flag) {
      this.vecSource.clear()
      this.map.removeLayer(this.vecLayer)
      this.overlayexs.clear()
    }

    if (this.draw) {
      this.draw.un('drawstart', this.onDrawStart)
      this.draw.un('drawend', this.onDrawEnd)
      this.map.removeInteraction(this.draw)
    }
  }
}
export default TyMeasureTool
